package com.googlecode.horncomb.web.spring.mvc.support;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
import org.springframework.web.servlet.mvc.multiaction.MethodNameResolver;
import org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException;

public class SimpleParameterMethodNameResolver implements MethodNameResolver {
	protected final Log logger = LogFactory.getLog(getClass());

	/**
	 * Default name for the parameter whose value identifies the method to
	 * invoke: "event".
	 */
	public static final String DEFAULT_PARAM_NAME = "event";

	private String paramName = DEFAULT_PARAM_NAME;

	private String defaultMethodName;

	public String getHandlerMethodName(HttpServletRequest request)
			throws NoSuchRequestHandlingMethodException {
		String methodName = null;

		methodName = request.getParameter(this.paramName);
		if (methodName != null) {
			if (logger.isDebugEnabled()) {
				logger.debug("Determined handler method '" + methodName
						+ "' based on value of request parameter '"
						+ this.paramName + "'");
			}
		}

		if (methodName == null) {
			if (this.defaultMethodName != null) {
				// No specific method resolved: use default method.
				methodName = this.defaultMethodName;
				if (logger.isDebugEnabled()) {
					logger.debug("Falling back to default handler method '"
							+ this.defaultMethodName + "'");
				}
			} else {
				// If resolution failed completely, throw an exception.
				throw new NoSuchRequestHandlingMethodException(request);
			}
		}

		return methodName;
	}

	/**
	 * Set the name of the parameter whose <i>value</i> identifies the name of
	 * the method to invoke. Default is "action".
	 * <p>
	 * Alternatively, specify parameter names where the very existence of each
	 * parameter means that a method of the same name should be invoked, via the
	 * "methodParamNames" property.
	 * @see #setMethodParamNames
	 */
	public void setParamName(String paramName) {
		if (paramName != null) {
			Assert.hasText(paramName, "'paramName' must not be empty");
		}
		this.paramName = paramName;
	}

	/**
	 * Set the name of the default handler method that should be used when no
	 * parameter was found in the request
	 */
	public void setDefaultMethodName(String defaultMethodName) {
		if (defaultMethodName != null) {
			Assert.hasText(defaultMethodName,
					"'defaultMethodName' must not be empty");
		}
		this.defaultMethodName = defaultMethodName;
	}

}
